let nodeIdSeed = 0;

export default class Node {
  constructor(data, meta) {
    this.id = nodeIdSeed++;
    this.data = data;
    this.meta = meta;
    this.childNodes = [];
    resolveNode(this);
  }

  label() {
    return getPropertyFromData(this, "label");
  }
  children() {
    return getPropertyFromData(this, "children");
  }
  key() {
    const nodeKey = this.meta.key;
    if (this.data) return this.data[nodeKey];
    return null;
  }

  disabled() {
    return getPropertyFromData(this, "disabled");
  }

  expand() {
    this.expanded = true;
  }

  collapse() {
    this.expanded = false;
  }
}
const resolveNode = (node) => {
  const { data, meta } = node;
  const key = node.key();

  if (meta.expandAll) node.expanded = true;
  else if (meta.expandedKeys && meta.expandedKeys.length > 0) {
    const expanded = meta.expandedKeys.includes(node[key]);
    node.expanded = expanded;
  }

  const childrenKey = meta["children"];
  const isParent = data[childrenKey] && data[childrenKey].length > 0;
  node.isParent = isParent;
  if (isParent) {
    node.childNodes = data[childrenKey].map((n) => {
      var child = new Node(n, { ...meta });
      child.parent = node;
      return child;
    });
  }
  return node;
};
const getPropertyFromData = (node, prop) => {
  const { data, meta } = node;
  const config = meta[prop];

  if (typeof config === "function") {
    return config(data, node);
  } else if (typeof config === "string") {
    return data[config];
  } else if (typeof config === "undefined") {
    const dataProp = data[prop];
    return dataProp === undefined ? "" : dataProp;
  }
};
